package com.xhsj.user.hr.process.processDefinition.service;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xhsj.user.hr.base.BaseService;
import com.xhsj.user.hr.process.dto.processDefinition.AddBusinessDto;
import com.xhsj.user.hr.process.dto.processDefinition.ListBusinessDto;
import com.xhsj.user.hr.process.dto.processDefinition.TbGlobalWorkFlowNodeDto;
import com.xhsj.user.hr.process.processDefinition.entity.TbGlobalBusiness;
import com.xhsj.user.hr.process.processDefinition.entity.TbGlobalWorkFlowNode;
import com.xhsj.user.hr.process.processDefinition.entity.TbGlobalWorkFlowNodeJudge;
import com.xhsj.user.hr.process.processDefinition.mapper.TbGlobalBusinessMapper;
import com.xhsj.user.hr.process.processDefinition.query.ListBusinessQuery;
import com.xhsj.user.hr.process.processDefinition.query.ShowBusinessQuery;
import com.xhsj.user.hr.process.processDefinition.query.TbGlobalWorkFlowNodoJudgeQuery;
import com.xhsj.user.properties.RoleKeyNameProperites;
import com.xhsj.user.hr.system.mapper.TbGlobalRoleMapper;
import com.xhsj.user.utils.Message;
import com.xhsj.user.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.io.Serializable;
import java.util.*;

/**
 * <p>
 * 流程设计-流程申请匹配表 服务实现类
 * </p>
 *
 * @author liuqinghua
 * @since Aug 28, 2020 4:37:27 PM
 */
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
//@CacheConfig(cacheNames = "TbGlobalBusiness")
public class TbGlobalBusinessService extends BaseService<TbGlobalBusinessMapper, TbGlobalBusiness> {
    @Autowired
    private TbGlobalBusinessMapper dao;

    // 流程设计-流程节点 服务实现类
    @Autowired
    private TbGlobalWorkFlowNodeService tbGlobalWorkFlowNodeService;


    // 流程-任务审核表 服务实现类
    @Autowired
    private TbGlobalApprovalTaskService tbGlobalApprovalTaskService;


	/**
	 * 保存
	 * @author liuqinghua
	 * @date Aug 28, 2020 4:37:27 PM
	 */
    @Override
    //@CacheEvict(cacheNames="TbGlobalBusiness", allEntries=true)
    public boolean save(TbGlobalBusiness entity) {
        return super.save(entity);
    }

	/**
	 * 通过id获取数据
	 * @author liuqinghua
	 * @date Aug 28, 2020 4:37:27 PM
	 */
    @Override
    //@Cacheable(key = "#id",sync = true)
    public TbGlobalBusiness getById(Serializable id) {
        return super.getById(id);
    }

	/**
	 * 通过id删除数据
	 * @author liuqinghua
	 * @date Aug 28, 2020 4:37:27 PM
	 */
    @Override
    //@CacheEvict(cacheNames="TbGlobalBusiness", allEntries=true)
    public boolean removeById(Serializable id) {
        return super.removeById(id);
    }

	/**
	 * 批量删除数据
	 * @author liuqinghua
	 * @date Aug 28, 2020 4:37:27 PM
	 */
    //@CacheEvict(cacheNames="SysDict", allEntries=true)
    @Override
    public boolean removeByIds(Collection<? extends Serializable> idList) {
        return super.removeByIds(idList);
    }

	/**
	 * 分页查询数据
	 * @author liuqinghua
	 * @date Aug 28, 2020 4:37:27 PM
	 */
    //@Cacheable(key = "#data",sync = true)
    public IPage<TbGlobalBusiness> selectPage(Map<String,Object> data) {
        int currentPage=1;
        if (!Objects.isNull(data.get("page"))) {
            currentPage=(Integer) data.get("page");
        }
        int pageSize=20;
        if (!Objects.isNull(data.get("size"))) {
            pageSize=(Integer) data.get("size");
        }

        TbGlobalBusiness entity = JSON.parseObject(JSON.toJSONString(data), TbGlobalBusiness.class);
        Page<TbGlobalBusiness> page = new Page(currentPage,pageSize);
        QueryWrapper<TbGlobalBusiness> wrapper = new QueryWrapper(entity);
        return super.selectPage(page, wrapper);
    }

	/**
	 * 查询所有数据
	 * @author liuqinghua
	 * @date Aug 28, 2020 4:37:27 PM
	 */
    @Override
    //@Cacheable(value = "TbGlobalBusiness",sync = true)
    public List<TbGlobalBusiness> selectAll() {
        return super.selectAll();
    }


    /**
     * 流程列表展示
     * @author liuqinghua
     * @date Aug 28, 2020 4:36:28 PM
     */
    public IPage<ListBusinessQuery> listBusiness(ListBusinessDto data) {
        Page<ListBusinessQuery> page = new Page(data.getPage(),data.getSize());
        Integer dictId = data.getDictId();
        Integer organizationId = data.getOrganizationId();
        return dao.listBusiness(page,dictId,organizationId);
    }

    /**
     * @Description:  流程列表保存
     * @Param:  com.xhsj.user.hr.process.dto.ProcessDefinition.AddBusinessDto
     * @Author: liuqinghua
     * @Date: 2020/8/31
     */
    public Message addBusiness(AddBusinessDto data) throws Exception {

        // 保存流程设计-流程申请匹配表
        TbGlobalBusiness tbGlobalBusiness = StringUtils.toJavaBean(data, TbGlobalBusiness.class);
        if (!super.save(tbGlobalBusiness)) {
            throw new Exception("保存流程设计-流程申请匹配表异常");
        }

        boolean isJudgeId =  true;
        Long judgeId = 0L;
        // 保存流程设计-流程节点
        List<TbGlobalWorkFlowNodeDto> tbGlobalWorkFlowNodeList = data.getNodeList();
        for (TbGlobalWorkFlowNodeDto tbGlobalWorkFlowNodeDto : tbGlobalWorkFlowNodeList) {
            TbGlobalWorkFlowNode tbGlobalWorkFlowNode = StringUtils.toJavaBean(tbGlobalWorkFlowNodeDto, TbGlobalWorkFlowNode.class);
            TbGlobalWorkFlowNodoJudgeQuery tbGlobalWorkFlowNodoJudgeDto = tbGlobalWorkFlowNodeDto.getTbGlobalWorkFlowNodoJudgeDto();
            if (tbGlobalWorkFlowNodoJudgeDto != null) {
            if (tbGlobalWorkFlowNodoJudgeDto.getJudgeId() != null) {
            if (!tbGlobalWorkFlowNode.getRoleId().equals(String.valueOf(tbGlobalWorkFlowNodoJudgeDto.getRoleId()))) {
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    return Message.error(1, tbGlobalWorkFlowNodoJudgeDto.getJudgeName());
                }
                Long process1 = dao.getProcess(data.getOrganizationId(),data.getRoleId(), data.getDictId(),
                        data.getId(),tbGlobalWorkFlowNodoJudgeDto.getJudgeId());
                if (process1 != null) {
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    return Message.error(1,"流程已存在");
                }
                tbGlobalWorkFlowNode.setJudgeId(tbGlobalWorkFlowNodoJudgeDto.getJudgeId());
                isJudgeId = false;
                judgeId = tbGlobalWorkFlowNodoJudgeDto.getJudgeId();
            }
            }
            if (tbGlobalWorkFlowNode.getApproveOrderNo() == 1) {
                tbGlobalWorkFlowNode.setRoleId("0");
            }
           if(tbGlobalWorkFlowNodeList.size() == tbGlobalWorkFlowNode.getApproveOrderNo()){
               tbGlobalWorkFlowNode.setNextNo(tbGlobalWorkFlowNode.getApproveOrderNo()+1);
            }
            tbGlobalWorkFlowNode.setCreateBy(data.getCreateBy());
            tbGlobalWorkFlowNode.setId(null);
            tbGlobalWorkFlowNode.setBusinessId(tbGlobalBusiness.getId());

            if (!tbGlobalWorkFlowNodeService.save(tbGlobalWorkFlowNode)) {
                throw new Exception("保存流程设计-流程节点异常");
            }
        }

        // 保存流程申请表
        TbGlobalBusiness tbGlobalBusiness1 = new TbGlobalBusiness();
        tbGlobalBusiness1.setRoleId(tbGlobalBusiness.getRoleId());
        tbGlobalBusiness1.setJudgeId(judgeId);
        tbGlobalBusiness1.setId(tbGlobalBusiness.getId());
        if (!super.updateById(tbGlobalBusiness1)) {
            throw new Exception("保存流程设计-流程节点异常");
        }

        if (isJudgeId) {
            // 判断是否有对应的流程
            Long process = dao.getProcess(data.getOrganizationId(),data.getRoleId(), data.getDictId(), tbGlobalBusiness.getId(), (long) 0);
            if (process != null) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Message.error(1,"流程已存在");
            }
        }

        TbGlobalWorkFlowNode lastTbGlobalWorkFlowNode = new TbGlobalWorkFlowNode();
        lastTbGlobalWorkFlowNode.setApproveOrderNo(tbGlobalWorkFlowNodeList.size()+1);
        lastTbGlobalWorkFlowNode.setTaskName("完结");
        lastTbGlobalWorkFlowNode.setCreateBy(data.getCreateBy());
        lastTbGlobalWorkFlowNode.setId(null);
        lastTbGlobalWorkFlowNode.setBusinessId(tbGlobalBusiness.getId());
        if (!tbGlobalWorkFlowNodeService.save(lastTbGlobalWorkFlowNode)) {
            throw new Exception("保存流程设计-加一个结束流程异常");
        }
        return Message.success("成功");
    }

    /**
     * @Description:  流程列表修改
     * @Param:  com.xhsj.user.hr.process.dto.ProcessDefinition.AddBusinessDto
     * @Author: liuqinghua
     * @Date: 2020/8/31
     */
    public Message updateBusiness(AddBusinessDto data) throws Exception {
        // 判断是否有正在执行的流程
        List<Long> runTask = tbGlobalApprovalTaskService.getRunTask(data.getId());
        if (runTask.size()==0) {
            // 删除流程设计-流程节点
            tbGlobalWorkFlowNodeService.deleteByBusinessId(data.getId());
            // 流程列表保存
            Message message = this.addBusiness(data);
            if ("1".equals(message.get("code"))) {
                throw new Exception("流程列表保存异常");
            }
            return message;
        }
        return Message.error("有正在执行的流程不能修改，需流程执行完");
    }

    /**
     * @Description:  启用禁用状态修改
     * @Author: liuqinghua
     * @Date: 2020/8/31
     */
    public void isEnableBusiness(long id, Integer isEnable) throws Exception {

        // 判断是否有正在执行的流程
        List<Long> runTask = tbGlobalApprovalTaskService.getRunTask(id);
        if (runTask.size() == 0) {
            TbGlobalBusiness tbGlobalBusiness = new TbGlobalBusiness();
            tbGlobalBusiness.setId(id);
            tbGlobalBusiness.setIsEnable(isEnable);
            if (!super.updateById(tbGlobalBusiness)) {
                throw new Exception("启用禁用状态修改异常");
            }
        } else {
            throw new Exception("有正在执行的流程不能禁用，需流程执行完");
        }


    }

    /**
     * @Description:  查看具体信息
     * @Author: liuqinghua
     * @Date: 2020/8/31
     */
    public ShowBusinessQuery showBusiness(long id) {
       return dao.showBusiness(id);
    }
}
